iT邦幫忙

2021 iThome 鐵人賽

DAY 11
1

試想一下,如果有個模型號稱有99%的準確率,那這個模型好不好呢?答案是不一定,在處理分類問題時,我們很常會遇到的一個狀況就是"資料不平衡",也就是負樣本的數量遠小於正樣本。

舉個例子,我們在分析信用卡盜刷的資料時,盜刷算是負樣本,發生的次數絕對比正常交易來的多,因此,若完全不做任何處理,我們的模型會大量的學習到正樣本的資料,在預測時很容易發生過度擬合(Over-fitting)的問題,假設正常比盜刷的比例是99:1,我們的模型預測100份資料都是正常,這樣的準確率是99%,可是他完全沒有預測到錯誤的那筆,那這個模型還有用嗎?因此,處理資料不平衡的問題也是一項重要的前處理!


一、不平衡資料(Imbalanced Data)

不平衡資料通常發生在良率分析、好壞分辨等案例,因為壞的都是少數案例,我們想要訓練模型挑出這些資料所做的分析。

那所謂不平衡的標準是多少呢?我們可以用鐵達尼號資料集看一下。

利用套件看出特徵的資料量

train_df['Survived'].value_counts()

https://ithelp.ithome.com.tw/upload/images/20210908/20140427edi5OdW4pN.jpg

畫出圓餅圖查看樣本比例

import matplotlib.pyplot as plt
plt.figure( figsize=(10,5) )
train_df['Survived'].value_counts().plot( kind='pie', colors=['lightcoral','skyblue'], autopct='%1.2f%%' )
plt.title( 'Survival' )  # 圖標題
plt.ylabel( '' )
plt.show()

https://ithelp.ithome.com.tw/upload/images/20210908/201404273EDNAYaLCo.jpg
可以看到比例存活與罹難的比例大概是6:4,這樣就是個差不多正常的比例。可以處理也可以不處理,接著讓我們來看看另一份資料集。

資料集下載地

這是一份半導體製造的良率分析,-1代表Pass,1代表Fail,資料占比如下

https://ithelp.ithome.com.tw/upload/images/20210908/20140427BbBqoDUlwZ.jpg
這樣的資料集就是比例相當懸殊的,我們必須經過處理後才能丟進模型訓練,否則就會發生過度擬合的問題,而處理方法分為上採樣(OverSampling)以及下採樣(UnderSampling)。


二、下採樣(UnderSampling)

下採樣的方法是透過刪除較多的樣本數,使兩個類別的樣本數量達到平衡,這樣的方法雖然方便,但其實缺點也很明顯,我們會失去大量的數據,以上面半導體的資料集來舉例,我們假如使用下採樣的方法,我們最後的資料集只會有原本的10%,這樣的方法其實是很不推薦的。


三、上採樣(OverSampling)

上採樣的作法與下採樣相反,是透過一些方法提升樣本數較少的資料,最常見的方法之一就是SMOTE,他是一種數據合成的方法,概念是在少數樣本附近的位置,"人工合成"出一些樣本,程式碼也非常簡單,我們以Secom的資料集來做示範。

先分出訓練集及測試集

要先做資料分割的動作的原因是,測試集是為了讓我們檢視最真實的評估結果,因此盡量保留它的完整性,不要去做過多的加工處理。

import numpy as np
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.3,random_state=11)

接著看一下資料的占比

import matplotlib.pyplot as plt
plt.figure( figsize=(10,5) )
y_train.value_counts().plot( kind='pie', colors=['lightcoral','skyblue'], autopct='%1.2f%%' )
plt.title( 'Pass/Fail' )  # 圖標題
plt.ylabel( '' )
plt.show()

https://ithelp.ithome.com.tw/upload/images/20210908/20140427HsZyYo32V0.jpg

做SMOTE處理

from imblearn.over_sampling import SMOTE
X_train, y_train = SMOTE().fit_resample(X_train, y_train)

看看成果

https://ithelp.ithome.com.tw/upload/images/20210908/20140427awiGFlHE6X.jpg


四、上採樣+下採樣

上採樣的效果明顯比下採樣還要來的好,但也存在一個缺點,因為我們會大量的對少數樣本附近進行複製,很可能合成出一些雜訊或是靠近正樣本的資料,而下採樣的方法中有一個叫做Tomek Link的方法,他的概念是能刪除一些邊界辨識度不高的樣本,因此我們可以先採用上採樣合成樣本後,再進行下採樣,把一些是雜訊的資料點剃除,程式碼也非常簡單。

from imblearn.under_sampling import TomekLinks
X_res, y_res = TomekLinks().fit_resample(X_train, y_train)

五、結論

資料不平衡的狀況在真實情況中蠻常發生的,今天也介紹了一些常見的處理方法,不管使用何種方法最好都透過交叉驗證去檢視資料的合理性,雖然合成的方法可能會缺少一點解釋力,畢竟資料是憑空出現的,我們也不好去解釋他,因此最好的處理方法還是想盡辦法去找到更多資料,希望這篇文章對大家有所幫助。


上一篇
DAY10 資料前處理-資料編碼、資料切割
下一篇
DAY12 特徵工程-資料化約(特徵選取)
系列文
學資料科學的小孩不會變壞- 從入門到實戰全攻略30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言